package proxy

import (
	"lktx-dns/config"
	"lktx-dns/entity"
	"lktx-dns/pool"
	"lktx-dns/stat"
	"log"
	"math/rand"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
	"time"
)

func getClientIP(r *http.Request) string {
	// 如果请求头中包含 X-Forwarded-For，返回其第一个 IP 地址
	if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
		// X-Forwarded-For 是以逗号分隔的 IP 地址列表，第一个是客户端的真实 IP
		parts := strings.Split(forwarded, ",")
		return strings.TrimSpace(parts[0])
	}
	// 如果没有 X-Forwarded-For 头部，则使用 RemoteAddr 获取客户端 IP
	host, _, _ := net.SplitHostPort(r.RemoteAddr)
	return host
}

func NewProxy(ip, port, host string) *httputil.ReverseProxy {
	target, err := url.Parse("http://" + ip + ":" + port)
	if err != nil {
		return nil
	}
	proxy := httputil.NewSingleHostReverseProxy(target)
	proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
		w.WriteHeader(http.StatusBadGateway)
	}
	proxy.BufferPool = pool.NewBuffer(32 * 1024)
	proxy.Transport = &http.Transport{
		MaxIdleConns:        1000,
		MaxIdleConnsPerHost: 500,
		IdleConnTimeout:     30 * time.Second,
	}
	proxy.ModifyResponse = func(response *http.Response) error {
		get := response.ContentLength
		if get > 0 {
			stat.StatData.AddDownload(host, get)
		}
		return nil
	}
	log.Println("初始化代理地址:" + host)
	return proxy
}

func Handler(w http.ResponseWriter, r *http.Request) {
	host := r.Host
	clientIP := getClientIP(r)
	stat.StatData.AddPv(host)
	stat.StatData.AddUv(host, clientIP)
	stat.StatData.AddIp(clientIP)
	stat.StatData.AddUpload(host, r.ContentLength)
	value, ok := config.Proxys.Load(host)
	if !ok {
		http.Error(w, host+":未配置代理转发", http.StatusInternalServerError)
		return
	}
	info := value.([]*entity.ProxyInfoEntity)
	rand.New(rand.NewSource(time.Now().UnixNano()))
	rand.Shuffle(len(info), func(i, j int) {
		info[i], info[j] = info[j], info[i]
	})
	infoEntity := info[0]
	if "1" == infoEntity.OpenIp {
		xfwd := r.Header.Get("X-Forwarded-For")
		if xfwd != "" {
			xfwd = xfwd + ", " + clientIP
		} else {
			xfwd = clientIP
		}
		r.Header.Set("X-Forwarded-For", xfwd)
	}
	if "1" == infoEntity.OpenCors {
		w.Header().Set("Access-Control-Allow-Origin", "*") // 允许所有域访问，或者替换为你需要的域名
		w.Header().Set("Access-Control-Allow-Methods", "*")
		w.Header().Set("Access-Control-Allow-Headers", "*")
		w.Header().Set("Access-Control-Allow-Credentials", "*")
		// 如果是 OPTIONS 请求，直接返回 200 响应
		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusOK)
			return
		}
	}
	if infoEntity.ReverseProxy == nil {
		proxy := NewProxy(*infoEntity.IP, *infoEntity.Port, host)
		if proxy == nil {
			http.Error(w, "错误URL地址", http.StatusInternalServerError)
			return
		}
		infoEntity.ReverseProxy = proxy
	}
	infoEntity.ReverseProxy.ServeHTTP(w, r)
}
